1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
| Array.from = (function () { var symbolIterator; try { symbolIterator = Symbol.iterator ? Symbol.iterator : 'Symbol(Symbol.iterator)'; } catch { symbolIterator = 'Symbol(Symbol.iterator)'; }
var toStr = Object.prototype.toString; var isCallable = function (fn) { return ( typeof fn === 'function' || toStr.call(fn) === '[object Function]' ); }; var toInteger = function (value) { var number = Number(value); if (isNaN(number)) return 0; if (number === 0 || !isFinite(number)) return number; return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); }; var maxSafeInteger = Math.pow(2, 53) - 1; var toLength = function (value) { var len = toInteger(value); return Math.min(Math.max(len, 0), maxSafeInteger); };
var setGetItemHandler = function setGetItemHandler(isIterator, items) { var iterator = isIterator && items[symbolIterator](); return function getItem(k) { return isIterator ? iterator.next() : items[k]; }; };
var getArray = function getArray( T, A, len, getItem, isIterator, mapFn ) { // 16. Let k be 0. var k = 0;
// 17. Repeat, while k < len… or while iterator is done (also steps a - h) while (k < len || isIterator) { var item = getItem(k); var kValue = isIterator ? item.value : item;
if (isIterator && item.done) { return A; } else { if (mapFn) { A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); } else { A[k] = kValue; } } k += 1; }
if (isIterator) { throw new TypeError( 'Array.from: provided arrayLike or iterator has length more then 2 ** 52 - 1' ); } else { A.length = len; }
return A; };
// The length property of the from method is 1. return function from(arrayLikeOrIterator /*, mapFn, thisArg */) { // 1. Let C be the this value. var C = this;
// 2. Let items be ToObject(arrayLikeOrIterator). var items = Object(arrayLikeOrIterator); var isIterator = isCallable(items[symbolIterator]);
// 3. ReturnIfAbrupt(items). if (arrayLikeOrIterator == null && !isIterator) { throw new TypeError( 'Array.from requires an array-like object or iterator - not null or undefined' ); }
// 4. If mapfn is undefined, then let mapping be false. var mapFn = arguments.length > 1 ? arguments[1] : void undefined; var T; if (typeof mapFn !== 'undefined') { // 5. else // 5. a If IsCallable(mapfn) is false, throw a TypeError exception. if (!isCallable(mapFn)) { throw new TypeError( 'Array.from: when provided, the second argument must be a function' ); }
// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined. if (arguments.length > 2) { T = arguments[2]; } }
// 10. Let lenValue be Get(items, "length"). // 11. Let len be ToLength(lenValue). var len = toLength(items.length);
// 13. If IsConstructor(C) is true, then // 13. a. Let A be the result of calling the [[Construct]] internal method // of C with an argument list containing the single item len. // 14. a. Else, Let A be ArrayCreate(len). var A = isCallable(C) ? Object(new C(len)) : new Array(len);
return getArray( T, A, len, setGetItemHandler(isIterator, items), isIterator, mapFn ); }; })();
|